# coding=utf-8
import qdarkstyle
from PyQt5.QtWidgets import QApplication, QAction, QWidget, QMainWindow, QGraphicsView, QGraphicsScene, QFileDialog
from PyQt5.QtCore import pyqtSignal, Qt, QRectF
from PyQt5.QtGui import QIcon, QImage, QImageWriter, QPainter
import Widget.ToolBar as tools
from GUI.Widget.ControllerPanel import ControlledPanel
import Tools.Transform as TransFrom


mainWindow = None  # 主窗口句柄

class MainWindow(QMainWindow):
    canvasShow = False
    canvasSize = (0, 0)
    trackMouseMove = False  # 不允许 自定义鼠标移动事件
    imageLayer = None   # 图层视图 小部件

    # 信号
    #selectedLayerChanged = pyqtSignal(list)  # 选择图层 变换信号

    def __init__(self):
        super().__init__()
        self.initUI()

    def initUI(self):
        # 得到桌面控件
        desktop = QApplication.desktop()
        # 得到屏幕可显示尺寸
        rect = desktop.availableGeometry()
        # 设置窗口尺寸
        self.setGeometry(rect)
        self.setWindowTitle('Photo Sprite Lite')
        self.setWindowIcon(QIcon('source/logo.png'))
        self.showMaximized()
        # 颜色
        self.setStyleSheet(qdarkstyle.load_stylesheet_pyqt5())

        self.show()
        # 创建菜单栏
        self.initMenu()
        # 图像面板
        self.initPanel()
        # 图像显示
        self.initImageView()
        #
        self.statusBar().showMessage('准备就绪')


    def initMenu(self):
        menuBar = self.menuBar()
        # menuBar.setStyleSheet('''background-color:#585858;color:#A4A4A4;''')
        fileMenu = menuBar.addMenu('文件')
        editorMenu = menuBar.addMenu('编辑')
        imageMenu = menuBar.addMenu('图像')
        filterMenu = menuBar.addMenu('滤镜')
        # 菜单添加选项
        # 文件
        actionList = []
        action = QAction('打开', self)
        action.setStatusTip('打开文件')
        action.triggered.connect(self.openFile)
        actionList.append(action)

        action = QAction('新建', self)
        action.setStatusTip('新建文件')
        action.triggered.connect(self.newFile)
        actionList.append(action)

        action = QAction('保存', self)
        action.setStatusTip('保存文件')
        action.triggered.connect(self.saveFile)
        actionList.append(action)

        action = QAction('另存为', self)
        action.setStatusTip('保存文件')
        actionList.append(action)
        # ction.triggered.connect#a(qApp.quit)
        for action in actionList:  # 添加选项
            fileMenu.addAction(action)
        # 编辑栏
        actionList.clear()
        action = QAction('几何变换', self)
        action.setStatusTip('几何变换')
        action.triggered.connect(self.transform)
        actionList.append(action)
        for action in actionList:  # 添加选项
            editorMenu.addAction(action)

    def initPanel(self):  # 面板
        w = self.geometry().width()
        h = self.geometry().height()
        margintop = 40
        marginbottom = 80
        # 工具栏
        panel = QWidget(self)
        # 设置窗口标记（无边框 ）
        panel.setWindowFlags(Qt.FramelessWindowHint)
        # 便于显示，设置窗口背景颜色(采用QSS)
        # panel.setStyleSheet('''background-color:#848484; ''')
        panel.setGeometry(0, margintop, w / 20, h - marginbottom - margintop)
        panel.show()
        self.toolPanel = panel
        # tools.setGeometry(panel.geometry())
        # 编辑栏
        panel = QWidget(self)
        # 设置窗口标记（无边框 ）
        # panel.setWindowFlags(Qt.FramelessWindowHint)
        # 便于显示，设置窗口背景颜色(采用QSS)
        panel.setObjectName('editorPanel')
        # panel.setStyleSheet('''background-color:#848484;color:#FFFFFF; ''')
        panel.setGeometry(w / 20, margintop, 15 * w / 20, 40)
        panel.show()
        self.editorPanel = panel
        # 图像面板
        panel = QWidget(self)
        # 设置窗口标记（无边框 ）
        panel.setWindowFlags(Qt.FramelessWindowHint)
        # 便于显示，设置窗口背景颜色(采用QSS)
        # panel.setStyleSheet('''background-color:#2E2E2E; ''')
        panel.setGeometry(w / 20, margintop + 40, 15 * w / 20, h - marginbottom - margintop - 40)
        panel.show()
        self.imagePanel = panel

        # 信息栏
        panel = QWidget(self)
        # 设置窗口标记（无边框 ）
        panel.setWindowFlags(Qt.FramelessWindowHint)
        # 便于显示，设置窗口背景颜色(采用QSS)
        # panel.setStyleSheet('''background-color:#424242; ''')
        panel.setGeometry(16 * w / 20, margintop, 4 * w / 20, 0.3 * (h - marginbottom - margintop))
        panel.show()
        self.infoPanel = panel

        # 图层栏
        panel = QWidget(self)
        # 设置窗口标记（无边框 ）
        panel.setWindowFlags(Qt.FramelessWindowHint)
        # 便于显示，设置窗口背景颜色(采用QSS)
        # panel.setStyleSheet('''background-color:#585858; ''')
        panel.setGeometry(16 * w / 20, margintop + 0.3 * (h - marginbottom - margintop), 4 * w / 20,
                          0.7 * (h - marginbottom - margintop))
        panel.show()
        self.layerPanel = panel

    def initImageView(self):
        # 图像显示主面板
        imagePanel = self.imagePanel
        graphics = QGraphicsView(imagePanel)
        graphics.setStyleSheet('border:None')
        # graphics.setGeometry(imagePanel.geometry())
        # graphics.setDragMode(QGraphicsView.NoDrag)  # 设置不能拖动
        self.graphicsView = graphics
        # 场景
        scene = QGraphicsScene(self)  # 创建场景
        graphics.setScene(scene)
        scene.setBackgroundBrush(Qt.transparent)
        self.scene = scene

        # 指示器面板
        imagePanel = self.imagePanel
        indicatorPanel = ControlledPanel(imagePanel)
        indicatorPanel.setWindowFlag(Qt.FramelessWindowHint)
        # controllerPanel.resize(400, 400)
        indicatorPanel.setGeometry(0, 0, imagePanel.geometry().width(), imagePanel.geometry().height())
        # controllerPanel.setAttribute(Qt.WA_StyledBackground, True)
        indicatorPanel.setStyleSheet("color: #FFFFFF;")

        # controllerPanel.setGeometry(imagePanel.geometry())
        # controllerPanel.show()
        # controllerPanel.setWindowFlag(Qt.imageWindow, False)
        self.indicatorPanel = indicatorPanel

    def mousePressGraphicsViewEvent(self, event):
        '''
        鼠标点击视图
        :param event: QMouseEvent
        :return:
        '''
        if event.button() == Qt.LeftButton:   # 左键
            # 工具方法
            toolBar = self.toolBar
            tool = toolBar.currentTool
            # print(tool.name)
            if hasattr(tool, 'mousePressGraphicsViewEventCallBack'):
                tool.mousePressGraphicsViewEventCallBack(tool, event)
        QGraphicsView.mousePressEvent(self.graphicsView, event)

    def mouseMoveGraphicsViewEvent(self, event):
        '''
        视图中移动鼠标
        :param event:
        :return:
        '''
        if self.trackMouseMove:
            # print('view 鼠标移动')
            # 工具方法
            toolBar = self.toolBar
            tool = toolBar.currentTool
            # print(tool.name)
            if hasattr(tool, 'mouseMoveGraphicsViewEventCallBack'):
                tool.mouseMoveGraphicsViewEventCallBack(tool, event)
        QGraphicsView.mouseMoveEvent(self.graphicsView, event)

    def mouseReleaseGraphicsViewEvent(self, event):
        '''
        鼠标释放视图
        :param event:
        :return:
        '''
        if event.button() == Qt.LeftButton:  # 左键
            # print('view 鼠标释放')
            # 工具方法
            toolBar = self.toolBar
            tool = toolBar.currentTool
            # print(tool.name)
            if hasattr(tool, 'mouseReleaseGraphicsViewEventCallBack'):
                tool.mouseReleaseGraphicsViewEventCallBack(tool, event)
        QGraphicsView.mouseReleaseEvent(self.graphicsView, event)

    def openFile(self):
        files = QFileDialog.getOpenFileName(self, '打开文件', './', 'Images (*.png *.xpm *.jpg)')
        imagePath = files[0]
        if imagePath != '':
            print(imagePath)
            self.App.openImage(imagePath)

    def saveFile(self):
        """
        保存文件
        """
        fileName = QFileDialog.getSaveFileName(self, '保存图片', './untitled.png', 'Images (*.png *.xpm *.jpg)')
        if fileName[0] != '':
            size = self.canvasSize  # 画布大小
            scene = self.scene
            view = self.graphicsView
            graphics = self.graphicsView
            image = QImage(size[0], size[1], QImage.Format_ARGB32)
            rect = scene.sceneRect()
            rect = QRectF(view.mapFromScene(rect.topLeft()), view.mapFromScene(rect.bottomRight()))
            print(rect.x(), ',', rect.y())
            qp = QPainter()
            qp.begin(image)
            graphics.render(qp, rect, rect.toRect())
            qp.end()
            writer = QImageWriter()
            writer.setFileName(fileName[0])
            writer.setQuality(100)
            # writer.setFormat('png')
            writer.write(image)
            print(writer.errorString())

    def newFile(self):
        self.App.newImage()

    def loadToolBar(self):
        """
        :加载工具
        :窗体左边的工具
        :return:
        """
        # 工具栏
        panel = self.toolPanel
        toolBar = tools.ToolBar(panel)
        self.toolBar = toolBar
        toolBar.loadTool()  # 加载工具功能

    def transform(self):
        currentLayer = self.imageLayer.currentItem()
        graphicsItem = currentLayer.graphicsItem
        if graphicsItem:
            TransFrom.Rotater
            scaler = TransFrom.Scaler(self.indicatorPanel, graphicsItem)
            # self.controllerPanel.addIndicator(scaler)
            # scaler.updateTagPos()
            self.indicatorPanel.setFocus()

    def initEvent(self):
        # 重载视图鼠标事件
        graphics = self.graphicsView
        graphics.mousePressEvent = self.mousePressGraphicsViewEvent
        graphics.mouseMoveEvent = self.mouseMoveGraphicsViewEvent
        graphics.mouseReleaseEvent = self.mouseReleaseGraphicsViewEvent

    def initSignals(self):
        """
        定义自定义的信号
        :return:
        """
        # 暂时不用
        # 图层获得工具焦点信号
        sig = pyqtSignal()
        self.toolFocusLayer = sig

    def forItemsInScene(self, filter = None):
        """
        遍历场景中所有item并通过filter函数过滤，返回一个列表
        :param filter: 过滤函数,它应该返回一个boolean值
        :return: List of QGraphicsSceneItem
        """
        scene = self.scene
        items = scene.items()
        if filter:
            ret = []
            for item in items:
                if filter(item):
                    ret.append(item)
            return ret
        else:
            items

    def forItemAtPoint(self, pos, filter = None):
        """
        返回事件鼠标点下第一个 visible and enable 的GraphicsItem
        :param pos: QPointF #GraphicsItem.mapToScene(event.pos())
        :param filter: filter(QGraphicsItem)
        :return: list of QGraphicsItem
        """
        items = self.scene.items(pos)
        if filter:
            ret = []
            for each in items:
                if filter(each):
                    ret.append(each)
            return ret
        else:
            return items

    def resetGraphicsItemZIndex(self):
        """
        根据图层顺序，重置图层的GraphicsItem 在场景中的Z-index
        :return:
        """
        scene = self.scene
        imageLayer = self.imageLayer
        items = imageLayer.allItems
        length = len(items)
        if length > 0:
            for i in range(0, length):
                graphicsItem = items[i].graphicsItem
                graphicsItem.setZValue(length - i - 1)
                print(items[i].text(), '变更到Z：', length - i - 1)

    def layerRowChangedEvent(self):
        """
        图层顺序改变事件
        :return:
        """
        self.resetGraphicsItemZIndex()
